/**
 * Content 指的是 desk 上面的画板.
 *
 * Panel (new canvas)
 * ├── Desk (new canvas)
 * │   ├── Desktop
 * │   │   ├── Content (new canvas)
 */
import layout from '../../compute/v1/layout';

import events from '../../compute/v1/events';
import { ZRenderComp } from '../../../common/component/zrComp';
import { cubicInOut, cubicOut, cubicIn } from '../../../common/animation/index';
import DeskAnimation from '../../compute/v1/deskAnimation';

let contentId = 0;

/**
 * 用于裁剪的 shape
 */
let contentClipShape = null;

/**
 * 自带 div 和 zr 的组件.
 * 
 * div 的左右移动由 this.divLeft 控制, 当不在渐入渐出动画时, this.divLeft = 0
 */
class AbstractContent extends ZRenderComp {
	spDels = [];
	lastFooterOffset = -1;
	divLeft = 0;

	/** @type {number[]} */ zlevels = [];

	/**
	 * @param {DeskAnimation} deskAnimation
	 */
	constructor(parent, zrender, deskAnimation) {
		super(parent, zrender);
		this.deskAnimation = deskAnimation;

		// 判定 init 动画方向, true 表示从左边飞进来, false 表示从右边飞进来
		const _lay = layout.content;
		const initFromLeft = deskAnimation.index < deskAnimation.lastIndex;
		this.divLeft = initFromLeft ? -_lay.animationOffsetX : _lay.animationOffsetX;
		this.createNewZRenderInstance(
			_lay.x + this.divLeft, _lay.y, _lay.width, _lay.height, 'content-' + (++contentId), 35);
		this.div.style.opacity = '0';

		this.on(events.FOOTER_SWITCH, this.onFooterSwitch.bind(this));
		this.on(events.STYLE_LR_UPDATED, this.onStyleLRUpdated.bind(this));
	}

	init() {
		this.createAnimation('divLeft')
			.whenUpdated(p => this.onDivLeftUpdated(p.value))
			.update()
			.when(0, this.divLeft)
			.when(500, 0).easing(cubicInOut)
			.commit();

		this.createAnimation('opacity')
			.whenUpdated(p => this.onDivOpacityUpdated(p.value))
			.update()
			.when(200, 0)
			.when(500, 1).easing(cubicOut)
			.commit();

		const {zr} = this;
		const [x, y] = this.relativePos();
		const spDelBuilder = this.getClipShapeBuilder();

		this.spDels = this.zlevels.map(zlevel => {
			const sp = new spDelBuilder({
				style: {
					opacity: 0.99
				},
				position: [x - this.divLeft, y], z: 999, zlevel
			});
			zr.add(sp);
			return sp;
		});
	}

	onDivLeftUpdated(divLeft) {
		this.divLeft = divLeft;
		this.x = layout.content.x + this.divLeft;
	}

	onDivOpacityUpdated(opacity) {
		this.div.style.opacity = opacity + '';
	}

	getClipShapeBuilder() {
		if (contentClipShape != null) {
			return contentClipShape;
		}

		const {zrender} = this;
		return contentClipShape = zrender.Path.extend({
			type: 'contentClipShape',
			shape: {
				footOffset: 100,
			},
			buildPath: function (path, shape) {
				path.moveTo(-1000, -1000);
				path.lineTo(2000, -1000);
				path.lineTo(2000, 2000);
				path.lineTo(-1000, 2000);
				path.closePath();

				// 上面是外圈, 下面是抠掉里面的图案
				layout.contentShape.build(path, shape.footOffset, layout.desktop.width, layout.desktop.height);
			},
			style: {
				stroke: 'transparent',
				fill: '#FFF',
				blend: 'destination-out',
			}
		});
	}

	tick(now) {
		if (this.lastFooterOffset != this.deskAnimation.footerShapeOffset) {
			this.makeDirty(false);
			this.lastFooterOffset = this.deskAnimation.footerShapeOffset;
		}
		super.tick(now);
	}

	paint() {
		const ax = this.absolutePos()[0];
		this.div.style.left = ax + 'px';

		this.spDels.forEach(sp => sp.attr({
			shape: { footOffset: this.lastFooterOffset },
			position: [-this.divLeft, this.relativePos()[1]]
		}));
	}

	onFooterSwitch() {
		const {deskAnimation} = this;
		const destroyToLeft = deskAnimation.index >= deskAnimation.lastIndex;
		const offsetX = layout.content.animationOffsetX;

		this.clearAnimations();
		this.createAnimation('divLeft')
			.whenUpdated(p => this.onDivLeftUpdated(p.value))
			.update()
			.when(0, 0)
			.when(500, destroyToLeft ? -offsetX : offsetX).easing(cubicInOut)
			.commit();

		this.createAnimation('opacity')
			.whenUpdated(p => this.onDivOpacityUpdated(p.value))
			.update()
			.when(0, 1)
			.when(300, 0).easing(cubicIn).callback(() => this.destroy())
			.commit();
	}

	onStyleLRUpdated() {
		this.makeDirty(true);
	}
}


export {
	AbstractContent
};
